import { Injectable } from "@angular/core";
import { Http, Headers, Response } from "@angular/http";
import { Router } from "@angular/router";
import { Observable } from "rxjs/Observable";
import { Subject } from "rxjs/Subject";
import { ReplaySubject } from "rxjs/ReplaySubject";
import "rxjs/add/operator/map";
import "rxjs/add/operator/catch";
import { LOGOS, USERURL, APISURL } from "shared";
import { User } from "./user.model";

import { Location } from "@angular/common";

interface LoginUser {
  mobile: string;
  passwd: string;
  userAgent?: string;
}

interface SignUser {
  mobile: string;
  smsCode: string;
  smsToken?: string;
}

interface MobileUser {
  mobile: string;
  smsCode: string;
  smsToken?: string;
  userAgent?: string;
}

interface FindUser {
  mobile: string;
  passwd: string;
  smsCode: string;
  smsToken: string;
}

interface BindUser {
  code: string;
  state: string;
  mobile: string;
  smsCode: string;
  smsToken: string;
}

interface PersonType {
  action: number;
  badge: number;
  cmsToken: string;
  jwt: string;
  status: number;
  badgeDiscovery?: number;
  badgeHome?: number;
  badgeLearn?: number;
  loginOps?: string;
  user?: UserType[];
}

interface UserType {
  bindQy: boolean;
  bindWx: boolean;
  customerCode: string;
  iconUrl: string;
  loginName: string;
  loginOps: string;
  mobile: string;
  name: string;
  passwd: boolean;
  totalContract: number;
  totalOrder: number;
  userId: number;
  verified: boolean;
}

interface ProfileType{
  user_id: string;
  name: string;
  mobile: string;
  packages: number[];
  access_level: string[];
  is_staff: number;
}

@Injectable()
export class UserService {
  appAgent: string;
  headers = new Headers();

  constructor(
    private http: Http, 
    private router: Router, 
    private location: Location
  ) {
    router.events.subscribe(this.successHandler);
    
    let userService = this;
    window.updatePages = function (url) {
      userService.updateLoginedState(url);
    }
    // let elec  = require('electron');
    // if (elec && elec.remote) {
    //   this.appAgent = elec.remote.getGlobal("appAgent");
    // }
    // this.appAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.89";
    // this.headers.append("User-Agent",this.appAgent);
  }
  defaultUserAvatar: string = LOGOS.defaultUserAvatar;
  userIconText: string;
  currentModal: string;
  isLogined: boolean = false;
  isToken: boolean;
  loginStatusSub = new ReplaySubject<any>(1);
  loginStatusReplaySub = new ReplaySubject<any>(1);
  userSub = new ReplaySubject<any>(1);
  tokenSub = new ReplaySubject<any>(1);
  personSub = new ReplaySubject<any>(1);

  profileOfUser:ProfileType;
  accessLevelSub = new ReplaySubject<any>(1);

  person: PersonType;
  // showLoginModalSub = new Subject<any>();

  // 当前路由状态;
  currentState: string;
  //  获取用户信息错误
  errText: string = "";
  successHandler = (param) => {
    let reg = param["url"].match(/^\/([a-zA-Z]+[^\/])/);  // id, url, urlAfterRedirects
    let state = reg ? reg[1] : null;
    this.currentState = state ? state : "stock";
    // console.debug("Router Handler: ", param.url, reg, state);
  }
  
  updateLoginedState(url: string) {
    this.setModal("hide");
    this.queryUser();
    // this.router.navigateByUrl(url);
    // this.router.navigate(["/"], { queryParams: { code: this.GetQueryString( url,"code"), state: this.GetQueryString( url,"state")} });
    if (this.isLogined === false) {
      this.router.navigateByUrl(url);
      if (this.GetQueryString(url, "code") !== null && this.GetQueryString(url, "state") !== null) {
        this.setModal("bindMobile");
      }
    }
  }

  GetQueryString(url:string,name:string) {
    var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
    var r = url.substr(2).match(reg);
    if (r != null) return r[2];
    return null;
  }

  setModal(action: string) {
    // console.info("current action: ", action);
    switch (action) {
      case "hide":
        this.currentModal = "";
        break;
      case "login":
        this.currentModal = "login";
        break;
      case "signup":
        this.currentModal = "signup";
        break;
      case "findpwd":
        this.currentModal = "findpwd";
        break;
      case "wechat":
        this.currentModal = "wechat";
        break;
      case "qywechat":
        this.currentModal = "qywechat";
        break;
      case "bindMobile":
        this.currentModal = "bindMobile";
        break;
      case "openService":
        this.currentModal = "openService";
        break;
      case "developing":
        this.currentModal = "developing";
        break;
      // case "setting":
      //   this.currentModal = "setting";
      //   break;
      case "logout":
        this.logout();
        this.currentModal = "";
        break;
      default:
        this.currentModal = "";
        break;
    }
  }

  // 更新登录状态
  updateLogStatus(status: boolean) {
    if (this.person && this.person.user ) {
      this.personSub.next(this.person.user);
    }
    this.isLogined = status;
    this.loginStatusSub.next(status);
    this.loginStatusReplaySub.next({
      isLogin: status
    });
    console.debug('更新了登录状态:', status);
    if (status) {
      this.setModal("hide");
    }
  }

  // queryUser() {
  //   this.http.get(`${BASEURL}/users/me`, { withCredentials: true })
  //     .map(res => res.json())
  //     .catch(err => {
  //       console.info("query user err: ", err);
  //       this.updateLogStatus(false);
  //       return Observable.throw(err);
  //     })
  //     .subscribe((data) => {
  //       console.info("user-account queryUser data: ", data);
  //       if (!data.hasOwnProperty('avatar')) {
  //         data['avatar'] = this.defaultUserAvatar;
  //       }
  //       // 推送用户数据
  //       this.userSub.next(data);
  //       this.user = data;
  //       this.userIconText = data.nick ? data.nick.charAt(0) : (data.username ? data.username.charAt(0) : "股");
  //       this.updateLogStatus(true);
  //     }, (err) => {
  //       console.info("query user err: ", err);
  //       this.updateLogStatus(false);
  //     });
  // }

  queryUser() {
    this.getSessionMe().subscribe((data) => {
      console.info("user-account queryUser data: ", data);
      // if (!data.hasOwnProperty('avatar')) {
      //   data['avatar'] = this.defaultUserAvatar;
      // }
      // 推送用户数据
      // this.userSub.next(data);
      // this.userIconText = data.nick ? data.nick.charAt(0) : (data.username ? data.username.charAt(0) : "股");
      // this.updateLogStatus(true);
      this.person = data.data;
      if ( this.person.status === 1 ) {
        this.updateLogStatus(true);
        this.getAccessLevel();
        this.isToken = true;
        
        //记录websocket专用token
        window.sessionStorage.setItem("scToken", data.data.scToken);
      } 
      else {
        this.errText = data.msg;
        this.updateLogStatus(false);
        switch (this.person.action) {
          case 0:
            this.isToken = true;
            this.tokenSub.next("Token");
            break;
          case 1:
            this.isToken = false;
            this.tokenSub.next("toLogin");
            break;
          default:
            this.isToken = false;
            this.tokenSub.next("toLogin");
            break;
        }
      }
    }, (err) => {
      console.info("query user err: ", err);
      alert("服务连接超时，请稍后重试！");
      this.updateLogStatus(false);
      return Observable.throw(err);
    });
  }

  logout() {
    this.http.post(`${USERURL}/api/v2/uc/session/out`, {}, { headers: this.headers, withCredentials: true })
      .catch(error => { 
        this.alertMessage();   
        console.info("get logout:", error);
        return Observable.throw(error); 
      })
      .subscribe((data) => {
        console.info("user logedout err: ", data, data.json());
        this.queryUser();
        // 在交易和直播页,则跳转到个股页
        this.router.navigate(["/comments"]);
        // this.location.go("/");
        // location.reload();
      });
  }
  
  // 自动登录
  getSessionMe() {
    return this.http.post(`${USERURL}/api/v2/uc/session/me`, { }, { headers: this.headers, withCredentials: true })
      .map(res => res.json())
      .catch(error => { 
        this.alertMessage();   
        console.info("get sessionMe err:", error);
        return Observable.throw(error); 
      });
  }

  signup(user: SignUser) {
    return this.http.post(`${USERURL}/api/v2/uc/account/mobile`, user, { headers: this.headers, withCredentials: true })
      .map(res => res.json())
      .catch(error => { 
        this.alertMessage();   
        console.info("signup err:", error);
        return Observable.throw(error); 
      });
  }

  sendSmsCode( url: string, uname: string) {
    return this.http.post(`${USERURL}/api/v2/uc/sms/` + url, { mobile: uname }, { headers: this.headers, withCredentials: true })
      .map(res => res.json())
      .catch(error => { 
        this.alertMessage();   
        console.info("send SmsCode err:", error);
        return Observable.throw(error); 
      });
  }

  login(user: LoginUser) {
    // user.userAgent = this.appAgent;
    return this.http.post(`${USERURL}/api/v2/uc/session/password`, user, { headers: this.headers, withCredentials: true })
      .map(res => res.json())
      .catch(error => { 
        this.alertMessage();   
        console.info("login err:", error);
        return Observable.throw(error); 
      });
  }

  mobileLogin(user: MobileUser) {
    // user.userAgent = this.appAgent;
    return this.http.post(`${USERURL}/api/v2/uc/session/mobile`, user, { headers: this.headers, withCredentials: true })
      .map(res => res.json())
      .catch(error => { 
        this.alertMessage();   
        console.info("mobile Login err:", error);
        return Observable.throw(error); 
      });
  }

  changePwd(user: FindUser) {
    return this.http.post(`${USERURL}/api/v2/uc/person/passwd`, user, { headers: this.headers, withCredentials: true })
      .map(res => res.json())
      .catch(error => { 
        this.alertMessage();   
        console.info("change Pwd err:", error);
        return Observable.throw(error); 
      });
  }
  
  bindMobile(user: BindUser) {
    return this.http.post(`${USERURL}/api/v2/uc/oauth/wx`, user, { headers: this.headers, withCredentials: true })
      .map(res => res.json())
      .catch(error => {
        this.alertMessage();
        console.info("bind mobile err:", error);
        return Observable.throw(error);
      })
  }

  getQyWechat() {
    //+window.location.origin+`%2frefresh.html
    return this.http.get(`${USERURL}/api/v2/uc/oauth/qy/qr?callback=`+window.location.origin+`%2frefresh.html`, { headers: this.headers, withCredentials: true })
      .map(res => res.json())
      .catch(error => { 
        this.alertMessage();   
        console.info("get QyWechat err:", error);
        return Observable.throw(error); 
      });
  }

  getWechat() {
    return this.http.get(`${USERURL}/api/v2/uc/oauth/wxqr?callback=`+window.location.origin+`%2frefresh.html`, { headers: this.headers, withCredentials:true })
      .map(res=>res.json())
      .catch(error => { 
        this.alertMessage();   
        console.info("get Wechat err:", error);
        return Observable.throw(error); 
      });
  }

  getProfile() {
    return this.http.get(`${APISURL}/qywxUser/profile`, { headers: this.headers, withCredentials:true })
      .map(res => res.json())
      .catch(error => {
        this.alertMessage();
        console.info("get Profile err:", error);
        return Observable.throw(error);
      })
  }

  setUser() {
    // this.userSub.next(data);
    this.getSessionMe().subscribe((data) => {
      this.person = data.data;
      if ( data.code !== 0 ) {
        this.errText = data.msg;
      }
      else {
        this.updateLogStatus(true);
        this.getAccessLevel();
      }
    });
    // localStorage.setItem("id_token", btoa(encodeURIComponent(JSON.stringify(this.user))));
  }

  private getAccessLevel() {
    this.getProfile().subscribe((data) => {
      if( data.code === 0 && data.msg === "success" ) {
        //Todo
        this.profileOfUser = data.data;
        this.accessLevelSub.next(this.profileOfUser.access_level);
      } else if ( data.code === 1002 && data.msg === "Expired token") {
        this.updateLogStatus(false);
        this.setModal("login");
      }
    });
  }

  oauth(type: string) {
    // https://api.58caimi.com/v1/auth/ for production
    let url;
    switch (type) {
      case "wechat":
        // url = `${USERURL}/api/v2/uc/oauth/wxweb?callback=` + location.href;
        // location.href = url;
        this.setModal("wechat");
        // alert("功能正在开发中，敬请期待！")
        break;
      case "qywechat":
        // url = `${USERURL}/api/v2/uc/oauth/qy/entry?callback=` + location.href;
        // location.href = url;
        this.setModal("qywechat");
        break;
      default:
        break;
    }
    // let electron = require('electron');    
    // electron && electron.ipcRenderer.on("login-reply",() => {
    //   this.setModal("hide");
    //   this.queryUser();
    //   this.router.navigate([this.location.path()]);
    // });

  }

  // 通过id获取用户信息
  // gerUserInfoById(userId: string) {
  //   let url = `${BASEURL}/users/` + userId;
  //   return this.http.get(url, { withCredentials: true })
  //     .map(res => res.json());
  // }

  private alertMessage() {
    alert("服务连接超时，请稍后重试！");
  }
}